namespace MyCompany.Views {
	using System;
	using System.ComponentModel;
	using System.Windows;
	using System.Windows.Threading;

	using SolidMvvm;

	using ViewModels;

	public partial class MyApplicationView : IView, MyApplicationViewModel.IMyApplicationViewModelObserver {
		static readonly GridLength GridLengthZero = new GridLength(0);

		readonly DispatcherTimer dispatcherTimerUpdateLog = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1000) };

		readonly ViewHelper<MyApplicationView, MyApplicationViewModel> viewHelper;

		bool isLogTextChanged;

		WPFDialog wpfDialog;

		public MyApplicationView() {
			InitializeComponent();

			viewHelper = new ViewHelper<MyApplicationView, MyApplicationViewModel>(this);
		}

		public void DisconnectFromViewModel() {
			viewHelper.ViewModel.MyApplicationViewModelObserver = null;
			dispatcherTimerUpdateLog.Stop();
			dispatcherTimerUpdateLog.Tick -= dispatcherTimerUpdateLog_Tick;
		}

		public void HideLogDialogDelegate() {
			if (wpfDialog != null) {
				wpfDialog.Content = null; // Trigger view to disconnect from view model.
				wpfDialog.Dispose();
				wpfDialog = null;
			}
		}

		public void ShowLogDialogDelegate() {
			wpfDialog = new WPFDialog(false, WPFDialog_CloseRequestedDelegate) { Content = viewHelper.ViewModel._LogViewModel, Title = "Log" };
			wpfDialog.ShowDialog(Window.GetWindow(this));
		}

		public void ShowMessageBoxDelegate() {
			MessageBox.Show("This is an MVVM-style message box.");
		}

		public bool ShowPromptToConfirmApplicationClose() {
			return MessageBox.Show("Allow the application to close?", "Close", MessageBoxButton.OKCancel, MessageBoxImage.Question, MessageBoxResult.Cancel) == MessageBoxResult.OK;
		}

		public void OnViewModelRemoved() {
			DisconnectFromViewModel();
		}

		public void OnViewModelApplied() {
			viewHelper.ViewModel.MyApplicationViewModelObserver = this;

			dispatcherTimerUpdateLog.Tick += dispatcherTimerUpdateLog_Tick;
			dispatcherTimerUpdateLog.Start();
		}

		public void OnPropertyChanged(PropertyChangedEventArgs propertyChangedEventArgs) {
			if (propertyChangedEventArgs.PropertyName == "_OutputText")
				isLogTextChanged = true;
		}

		void dispatcherTimerUpdateLog_Tick(object sender, EventArgs e) {
			if (viewHelper.ViewModel != null) {
				textBoxLogViewer.Text = viewHelper.ViewModel._OutputText;

				if (viewHelper.ViewModel._IsLogViewerVisible) {
					if (grid.RowDefinitions[3].Height.Equals(GridLengthZero)) {
						grid.RowDefinitions[2].Height = new GridLength(5);
						grid.RowDefinitions[3].Height = new GridLength(200);
					}

					if (isLogTextChanged) {
						isLogTextChanged = false;
						textBoxLogViewer.ScrollToEnd();
					}
				}
				else if (!grid.RowDefinitions[3].Height.Equals(GridLengthZero)) {
					grid.RowDefinitions[2].Height = GridLengthZero;
					grid.RowDefinitions[3].Height = GridLengthZero;
				}
			}
		}

		void WPFDialog_CloseRequestedDelegate(WPFDialog sender) {
			viewHelper.ViewModel._CloseLogDialogRequested();
		}
	}
}
